import {ComponentPortal, PortalInjector} from "@angular/cdk/portal";
import { OverlayRef, Overlay} from "@angular/cdk/overlay";
import {BehaviorSubject, combineLatest, merge, Observable, of, Subject, Subscription} from "rxjs";
import {PanelComponent} from "./panel.component";
import {AfterViewInit, Component, Inject, Injector, OnInit, ViewChild} from "@angular/core";
import { S2S_ETD_DETAIL } from "./panel.component";
import {CollectionViewer, DataSource} from "@angular/cdk/collections";
import {AvPaginationComponent} from "../../../../../shared/components/av-pagination/av-pagination.component";
import {filter, map, takeUntil} from "rxjs/operators";
import {AvtSortDirective} from "../../../../../shared/components/simple-table/avt-sort.directive";
import {NzPaginationComponent} from "ng-zorro-antd/pagination";

interface PersonInfo {
    name: string;
    age: number | string;
    address: string;
    brith: string;
    city: string;
    work: string
}
const d: PersonInfo[] = [
  { name: 'wang', age: '12',  address: '花山', brith: '1996-09-01', city: 'wuhan', work: 'web 前端' },
  { name: 'wang', age: '14', address: '花山', brith: '1996-09-01', city: 'wuhan', work: 'web 前端' },
  { name: 'wang', age: '14', address: '花山', brith: '1996-09-01', city: 'wuhan', work: 'web 前端' },
  { name: 'wang', age: '14', address: '花山', brith: '1996-09-01', city: 'wuhan', work: 'web 前端' },
  { name: 'wang', age: '14', address: '花山', brith: '1996-09-01', city: 'wuhan', work: 'web 前端' },
  { name: 'wang', age: '14', address: '花山', brith: '1996-09-01', city: 'wuhan', work: 'web 前端' },
  { name: 'wang', age: '14', address: '花山', brith: '1996-09-01', city: 'wuhan', work: 'web 前端' },
  { name: 'wang', age: '17', address: '花山', brith: '1996-09-01', city: 'wuhan', work: 'web 前端' },
  { name: 'wang', age: '14', address: '花山', brith: '1996-09-01', city: 'wuhan', work: 'web 前端' },
  { name: 'wang', age: '25', address: '花山', brith: '1996-09-01', city: 'wuhan', work: 'web 前端' },
  { name: 'wang', age: '14', address: '花山', brith: '1996-09-01', city: 'wuhan', work: 'web 前端' },
  { name: 'wang', age: '14', address: '花山', brith: '1996-09-01', city: 'wuhan', work: 'web 前端' },
  { name: 'wang', age: '14', address: '花山', brith: '1996-09-01', city: 'wuhan', work: 'web 前端' },
  { name: 'wang', age: '19', address: '花山', brith: '1996-09-01', city: 'wuhan', work: 'web 前端' },
  { name: 'wang', age: '14', address: '花山', brith: '1996-09-01', city: 'wuhan', work: 'web 前端' },
  { name: 'wang', age: '18', address: '花山', brith: '1996-09-01', city: 'wuhan', work: 'web 前端' },
  { name: 'wang', age: '22', address: '花山', brith: '1996-09-01', city: 'wuhan', work: 'web 前端' },
  { name: 'wang', age: '14', address: '花山', brith: '1996-09-01', city: 'wuhan', work: 'web 前端' },
  { name: 'wang', age: '14', address: '花山', brith: '1996-09-01', city: 'wuhan', work: 'web 前端' },
  { name: 'wang', age: '14', address: '花山', brith: '1996-09-01', city: 'wuhan', work: 'web 前端' },
  { name: 'wang', age: '14', address: '花山', brith: '1996-09-01', city: 'wuhan', work: 'web 前端' },
  { name: 'wang', age: '14', address: '花山', brith: '1996-09-01', city: 'wuhan', work: 'web 前端' },
  { name: 'wang', age: '14', address: '花山', brith: '1996-09-01', city: 'wuhan', work: 'web 前端' },
  { name: 'wang', age: '14', address: '花山', brith: '1996-09-01', city: 'wuhan', work: 'web 前端' },
  { name: 'wang', age: '14', address: '花山', brith: '1996-09-01', city: 'wuhan', work: 'web 前端' },
  { name: 'wang', age: '14', address: '花山', brith: '1996-09-01', city: 'wuhan', work: 'web 前端' },
  { name: 'wang', age: '14', address: '花山', brith: '1996-09-01', city: 'wuhan', work: 'web 前端' },
]

class TbDs implements DataSource<PersonInfo>{
  private _data = new BehaviorSubject<PersonInfo[]>(d)
  private _renderData = new BehaviorSubject<PersonInfo[]>([])

  get data() {
    return this._data.value;
  }
  set data(val){
    this._data.next(val)
  }

  // private _pagi: null | AvPaginationComponent = null;
  private _pagi: null | NzPaginationComponent = null;
  _renderChangeSubscription: Subscription| null = null
  get paginator() {
    return this._pagi
  }
  // set paginator(comp: AvPaginationComponent) {
  set paginator(comp: NzPaginationComponent) {
    this._pagi = comp;
    this._updateRender();
  }

  constructor(
  ) {
  }


  private _currentPageData(data: PersonInfo[], pageChange) {
    if (!this._pagi) {
      return data
    }
    let startIndex = (this._pagi.nzPageIndex - 1) * this._pagi.nzPageSize;
    return data.slice(startIndex, startIndex + this._pagi.nzPageSize)
  }

  private _updateRender() {
    // 总数据流
    let dataStream = this._data;
    // 是否有 paginator
    // 如果有 先合并 pagi 的 分页变化事件（ 当前页数， 每页条数）
    // 没有 使用 of(null)
    let paginaor$ = of(null);
    if (this._pagi) {
      paginaor$ = merge(
        this._pagi.nzPageIndexChange,
        this._pagi.nzPageSizeChange
      )
    }
    // combina 数据流
    let currentPage$ = combineLatest([dataStream, paginaor$]).pipe(
      map(([data, page]) => this._currentPageData(data, page))
    )
    // 订阅 这个数据流
    this._renderChangeSubscription?.unsubscribe()
    this._renderChangeSubscription = currentPage$.subscribe(d => {
      this._renderData.next(d)
    })
    this._pagi.nzPageIndexChange.next(
      this._pagi.nzPageIndex
    );
  }

  connect(): Observable<PersonInfo[]> {
    if (!this._renderChangeSubscription) {
      this._updateRender();
    }
    return this._renderData
  }
  disconnect() {
    this._renderChangeSubscription.unsubscribe();
    this._renderChangeSubscription = null;
  }

}

@Component({
  selector: 'app-cdk',
  template: `
    <button (click)="toggleOverLay()">Open OverLay</button>
    <table cdk-table [dataSource]="dataSource" avtSort class="ml-table">
      <ng-container cdkColumnDef="name">
        <th cdk-header-cell *cdkHeaderCellDef>name</th>
        <td cdk-cell *cdkCellDef="let element">{{ element.name }}</td>
      </ng-container>
      <ng-container cdkColumnDef="age">
        <th cdk-header-cell *cdkHeaderCellDef [tbSort]="true">age</th>
        <td cdk-cell *cdkCellDef="let element">{{ element.age }}</td>
      </ng-container>
      <ng-container cdkColumnDef="address">
        <th cdk-header-cell *cdkHeaderCellDef>address</th>
        <td cdk-cell *cdkCellDef="let element">{{ element.address }}</td>
      </ng-container>
      <ng-container cdkColumnDef="brith">
        <th cdk-header-cell *cdkHeaderCellDef>brith</th>
        <td cdk-cell *cdkCellDef="let element">{{ element.brith }}</td>
      </ng-container>
      <ng-container cdkColumnDef="city">
        <th cdk-header-cell *cdkHeaderCellDef>city</th>
        <td cdk-cell *cdkCellDef="let element">{{ element.city }}</td>
      </ng-container>
      <ng-container cdkColumnDef="work">
        <th cdk-header-cell *cdkHeaderCellDef>work</th>
        <td cdk-cell *cdkCellDef="let element">{{ element.work }}</td>
      </ng-container>

      <tr cdk-header-row *cdkHeaderRowDef="displayedColumns"></tr>
      <tr cdk-row *cdkRowDef="let row; columns: displayedColumns;"></tr>
    </table>
<!--    <app-av-pagination
      #pagi
      [itemsPerPage]="5"
      [currentPageIndex]="1"
      [totalItems]="dataSource.data?.length"
    >
    </app-av-pagination>-->
    <nz-pagination
      #pagi
      [nzPageIndex]="1"
      [nzPageSize]="5"
      [nzPageSizeOptions]="[2, 5, 10]"
      [nzTotal]="dataSource.data?.length"
      [nzShowSizeChanger]="true"
    >
    </nz-pagination>
    <!--    <button (click)="isOpen = !isOpen" #trigger>Open OverLay</button>-->
    <!--    <ng-template-->
    <!--      cdk-connected-overlay-->
    <!--      [cdkConnectedOverlayOrigin]="trigger"-->
    <!--      [cdkConnectedOverlayOpen]="isOpen"-->
    <!--      [cdkConnectedOverlayBackdropClass]="'custom-cdk-backdrop'"-->
    <!--      [cdkConnectedOverlayHasBackdrop]="true"-->
    <!--      (backdropClick)="isOpen = !isOpen"-->
    <!--    >-->
    <!--      <ul class="example-list" style="box-shadow: 0 0 2px #546e95; padding: 8px">-->
    <!--        <li>China</li>-->
    <!--        <li>India</li>-->
    <!--        <li>England</li>-->
    <!--      </ul>-->
    <!--    </ng-template>-->
  `,
  styleUrls: [
  ],
  styles: [
    `
      ul {
        background-color: #fff;
        border-radius: 3px;
        padding: 8px;
      }
      li {
        box-sizing: border-box;
        list-style: none;
      }
      .cdk-table {
        box-shadow: 0 5px 5px -3px #0003, 0 8px 10px 1px #00000024, 0 3px 14px 2px #0000001f;
        width: 80%;
        border-spacing: 0;
      }

      .cdk-header-cell {
        background: #546e95;
        color: #fff;
        text-align: left;
        border-right: 1px solid #fff;
      }
      .cdk-header-cell:first-of-type {
        padding-left: 10px;
        border-top-left-radius: 6px;
      }
      .cdk-header-cell:last-of-type {
        border-right: none;
        padding-right: 10px;
        border-top-right-radius: 6px;
      }
      .cdk-cell {
        border-bottom: 1px solid #ccc;
        border-right: 1px solid #ccc;
      }
      .cdk-cell:first-of-type {
        padding-left: 10px;
      }
      .cdk-cell:last-of-type {
        padding-right: 10px;
      }
      .cdk-row {
        height: 32px;
      }
      .cdk-header-row {
        height: 38px;
      }
    `
  ]
})
export class CdkComponent implements OnInit, AfterViewInit {

  constructor(
    private overLay: Overlay, private inject: Injector,
  ) { }

  isOpen$ = new BehaviorSubject<boolean>(false);
  isOpenObv$ = this.isOpen$.asObservable();
  overLayRef: OverlayRef;
  dataSource = new TbDs();
  displayedColumns = ['name', 'age', 'address', 'brith', 'city', 'work']
  // @ViewChild('pagi', { static: true }) pagi: AvPaginationComponent
  @ViewChild('pagi', { static: true }) pagi: NzPaginationComponent
  @ViewChild(AvtSortDirective) avtSort: AvtSortDirective
  toggleOverLay () {
    const val = this.isOpen$.getValue();
    this.isOpen$.next(!val);
  }
  ngAfterViewInit() {
    console.log(this.avtSort)
    this.dataSource.data = d;
    this.dataSource.paginator = this.pagi
  }

  ngOnInit(): void {
    const posBuilder = this.overLay.position();
    this.overLayRef = this.overLay.create({
      height: 'auto',
      width: '720px',
      hasBackdrop: false,
      backdropClass: 'custom-cdk-backdrop',
      positionStrategy: posBuilder.global()
        .top('100px')
        .centerHorizontally()
        // .centerVertically()
    })

    this.overLayRef.outsidePointerEvents().subscribe(v => {
      this.isOpen$.next(false);
    })



    const el = this.overLayRef.overlayElement
    el.classList.add('overlay-animate')
    PanelComponent.isOpen$ = this.isOpen$;
    // 传递数据
    const injectData = new WeakMap();
    injectData.set(S2S_ETD_DETAIL, {
      name: 'michael Wang', age: '25'
    })
    const panelComponentComponentPortal = new ComponentPortal(
      PanelComponent,
      null,
      new PortalInjector(this.inject, injectData)
    );
    this.isOpenObv$.subscribe(value => {
      if (value) {
        this.overLayRef.attach(panelComponentComponentPortal);
      } else {
        this.overLayRef.detach();
      }
    })

    this.overLayRef.backdropClick()
      .subscribe(ev => {
        this.isOpen$.next(false);
    });

  }

}
